#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDateTime>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    initUI();
    initSerial();
    on_refreshButton_clicked();

    // 初始化状态栏定时器
    statusTimer = new QTimer(this);
    connect(statusTimer, &QTimer::timeout, this, &MainWindow::updateStatus);
    statusTimer->start(1000); // 每秒更新一次
}

MainWindow::~MainWindow()
{
    savePortSettings();
    delete ui;
    delete serial;
    delete statusTimer;
}

void MainWindow::initUI()
{
    // 设置波特率选项
    ui->baudRateComboBox->addItems({"9600", "19200", "38400", "57600", "115200", "230400", "460800", "921600"});
    ui->baudRateComboBox->setCurrentText("115200");

    // 设置数据位选项
    ui->dataBitsComboBox->addItems({"5", "6", "7", "8"});
    ui->dataBitsComboBox->setCurrentText("8");

    // 设置校验位选项
    ui->parityComboBox->addItems({"None", "Even", "Odd", "Space", "Mark"});
    ui->parityComboBox->setCurrentIndex(0);

    // 设置停止位选项
    ui->stopBitsComboBox->addItems({"1", "1.5", "2"});
    ui->stopBitsComboBox->setCurrentText("1");

    // 设置流控制选项
    ui->flowControlComboBox->addItems({"None", "RTS/CTS", "XON/XOFF"});
    ui->flowControlComboBox->setCurrentIndex(0);

    // 禁用发送按钮
    ui->sendButton->setEnabled(false);

    // 设置接收区为只读
    ui->receiveTextEdit->setReadOnly(true);

    // 加载上次保存的设置
    loadPortSettings();
}

void MainWindow::initSerial()
{
    serial = new QSerialPort(this);
    connect(serial, &QSerialPort::readyRead, this, &MainWindow::readData);
    connect(serial, &QSerialPort::errorOccurred, [this](QSerialPort::SerialPortError error) {
        if (error != QSerialPort::NoError) {
            ui->statusBar->showMessage("串口错误: " + serial->errorString());
            on_openButton_clicked(); // 关闭串口
        }
    });
}

void MainWindow::on_openButton_clicked()
{
    if (serial->isOpen()) {
        // 关闭串口
        serial->close();
        ui->openButton->setText("打开串口");
        ui->sendButton->setEnabled(false);
        ui->portComboBox->setEnabled(true);
        ui->baudRateComboBox->setEnabled(true);
        ui->dataBitsComboBox->setEnabled(true);
        ui->parityComboBox->setEnabled(true);
        ui->stopBitsComboBox->setEnabled(true);
        ui->flowControlComboBox->setEnabled(true);
        ui->statusBar->showMessage("串口已关闭");
    } else {
        // 打开串口
        if (ui->portComboBox->currentText().isEmpty()) {
            ui->statusBar->showMessage("请选择串口");
            return;
        }

        serial->setPortName(ui->portComboBox->currentText().split(" - ").first());
        serial->setBaudRate(ui->baudRateComboBox->currentText().toInt());

        // 设置数据位
        switch (ui->dataBitsComboBox->currentText().toInt()) {
        case 5:
            serial->setDataBits(QSerialPort::Data5);
            break;
        case 6:
            serial->setDataBits(QSerialPort::Data6);
            break;
        case 7:
            serial->setDataBits(QSerialPort::Data7);
            break;
        case 8:
            serial->setDataBits(QSerialPort::Data8);
            break;
        default:
            serial->setDataBits(QSerialPort::Data8);
            break;
        }

        // 设置校验位
        switch (ui->parityComboBox->currentIndex()) {
        case 0:
            serial->setParity(QSerialPort::NoParity);
            break;
        case 1:
            serial->setParity(QSerialPort::EvenParity);
            break;
        case 2:
            serial->setParity(QSerialPort::OddParity);
            break;
        case 3:
            serial->setParity(QSerialPort::SpaceParity);
            break;
        case 4:
            serial->setParity(QSerialPort::MarkParity);
            break;
        default:
            serial->setParity(QSerialPort::NoParity);
            break;
        }

        // 设置停止位
        if (ui->stopBitsComboBox->currentText() == "1") {
            serial->setStopBits(QSerialPort::OneStop);
        } else if (ui->stopBitsComboBox->currentText() == "1.5") {
            serial->setStopBits(QSerialPort::OneAndHalfStop);
        } else if (ui->stopBitsComboBox->currentText() == "2") {
            serial->setStopBits(QSerialPort::TwoStop);
        } else {
            serial->setStopBits(QSerialPort::OneStop);
        }

        // 设置流控制
        switch (ui->flowControlComboBox->currentIndex()) {
        case 0:
            serial->setFlowControl(QSerialPort::NoFlowControl);
            break;
        case 1:
            serial->setFlowControl(QSerialPort::HardwareControl);
            break;
        case 2:
            serial->setFlowControl(QSerialPort::SoftwareControl);
            break;
        default:
            serial->setFlowControl(QSerialPort::NoFlowControl);
            break;
        }

        if (serial->open(QIODevice::ReadWrite)) {
            ui->openButton->setText("关闭串口");
            ui->sendButton->setEnabled(true);
            ui->portComboBox->setEnabled(false);
            ui->baudRateComboBox->setEnabled(false);
            ui->dataBitsComboBox->setEnabled(false);
            ui->parityComboBox->setEnabled(false);
            ui->stopBitsComboBox->setEnabled(false);
            ui->flowControlComboBox->setEnabled(false);
            ui->statusBar->showMessage("串口已打开: " + ui->portComboBox->currentText());
            savePortSettings();
        } else {
            ui->statusBar->showMessage("无法打开串口: " + serial->errorString());
        }
    }
}

void MainWindow::on_sendButton_clicked()
{
    if (!serial->isOpen()) {
        ui->statusBar->showMessage("串口未打开");
        return;
    }

    QString sendData = ui->sendTextEdit->toPlainText();
    if (sendData.isEmpty()) {
        return;
    }

    // 如果勾选了"发送新行"，添加换行符
    if (ui->newLineCheckBox->isChecked()) {
        sendData += "\r\n";
    }

    qint64 bytesWritten = serial->write(sendData.toLocal8Bit());
    if (bytesWritten == -1) {
        ui->statusBar->showMessage("发送失败: " + serial->errorString());
    } else if (bytesWritten != sendData.toLocal8Bit().size()) {
        ui->statusBar->showMessage("发送部分数据: " + QString::number(bytesWritten) + " / " + QString::number(sendData.toLocal8Bit().size()));
    } else {
        ui->statusBar->showMessage("发送成功: " + QString::number(bytesWritten) + " 字节");
    }
}

void MainWindow::on_clearButton_clicked()
{
    ui->receiveTextEdit->clear();
}

void MainWindow::on_refreshButton_clicked()
{
    ui->portComboBox->clear();

    // 获取所有可用串口
    foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
        ui->portComboBox->addItem(info.portName() + " - " + info.description());
    }

    if (ui->portComboBox->count() == 0) {
        ui->portComboBox->addItem("无可用串口");
        ui->openButton->setEnabled(false);
    } else {
        ui->openButton->setEnabled(true);
    }
}

void MainWindow::readData()
{
    QByteArray data = serial->readAll();
    if (!data.isEmpty()) {
        // 如果勾选了"显示时间戳"，添加时间戳
        if (ui->timestampCheckBox->isChecked()) {
            QDateTime currentDateTime = QDateTime::currentDateTime();
            QString timestamp = currentDateTime.toString("yyyy-MM-dd HH:mm:ss.zzz") + ": ";
            ui->receiveTextEdit->insertPlainText(timestamp);
        }

        // 根据显示格式选项显示数据
        if (ui->asciiRadioButton->isChecked()) {
            ui->receiveTextEdit->insertPlainText(QString(data));
        } else if (ui->hexRadioButton->isChecked()) {
#if QT_VERSION >= QT_VERSION_CHECK(6, 0, 0)
            QString hexData = data.toHex().toUpper();
            // 添加空格分隔
            hexData = hexData.replace(QRegularExpression("(..)"), "\\1 ").trimmed();
#else
            QString hexData = data.toHex(' ').toUpper();
#endif
            ui->receiveTextEdit->insertPlainText(hexData + " ");
        }

        // 自动滚动到底部
        ui->receiveTextEdit->moveCursor(QTextCursor::End);
    }
}

void MainWindow::updateStatus()
{
    if (serial->isOpen()) {
        // 显示串口状态
        ui->statusBar->showMessage("串口已打开: " + ui->portComboBox->currentText() + " | 接收: " + QString::number(serial->bytesAvailable()) + " 字节");
    }
}

void MainWindow::loadPortSettings()
{
    // 在实际应用中，可以从配置文件加载设置
    // 这里简单实现，使用默认值
}

void MainWindow::savePortSettings()
{
    // 在实际应用中，可以保存设置到配置文件
    // 这里简单实现，不做实际保存
}